/***************************************************************************
**
** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#ifndef ML10N_MLOCALE_H
#define ML10N_MLOCALE_H

#include "mlocaleexport.h"

#include <float.h>
#include <QtGlobal>
#include <QObject>
#include <QMap>

class QString;
class QStringList;
class QDateTime;
class QTranslator;

namespace ML10N {

class MCollator;
class MAbstractName;
class MCalendar;
class MBreakIteratorPrivate;

class MLocalePrivate;
class MLocaleAbstractConfigItemFactory;

struct MStaticLocaleDestroyer;

/*!
 * \class MLocale
 *
 * \brief MLocale is a class that implements locale dependent data formatting as well as translation, collation and calendar systems.
 *
 * For more general information about Internationalization in libmeegotouch
 * see also the <a href="i18n.html">Internationalization Guidelines</a>
 *
 * The locale system in the MeeGo Touch UI Framework is separated into
 * different categories. These correspond roughly to the LC_*
 * environment variables of POSIX. MLocale is created with one main
 * language setting but category settings can be used to override
 * specific details.  For example it is possible to set the main
 * language to “en_US” to get user interface messages in English but
 * set the MLcCollate category to “fi_FI” to get Finnish collation and
 * set the MLcNumeric category to “de_DE” to get German number
 * formatting.
 *
 * The calendar system in the MeeGo Touch UI Framework supports a
 * number of non-Gregorian calendar systems. The calendar is used to
 * create presentations of date and time.
 *
 * The collation system in the MeeGo Touch UI Framework supports a
 * number of collation systems. The actual collation is done with the
 * MCollator class.
 *
 * The translation system in the MeeGo Touch UI Framework differs a
 * bit from the usual practice used in any other translation system
 * (e.g, Qt’s tr() or GNU’s gettext). In the MeeGo Touch UI Framework,
 * a developer has to use both logical names and Engineering English
 * to translate a string.  Whenever no translation is available, the
 * Engineering English version, which is auto-generated from the
 * source code, is displayed instead of the logical names to make
 * testing easier.  The displayed Engineering English is prefixed with
 * “!! ” to make it obvious that no translation was found and a proper
 * translation still needs to be added.  Internally, the MeeGo
 * Touch UI Framework translation system uses the Qt translation
 * system (using the QTranslator class). The translation source file
 * is in .ts format version 3.0. Usually the translation source file
 * is not generated from code, but rather generated by some other
 * means (e.g from the UI specification).
 *
 * If one wants to react when the locale settings are changed, one can
 * connect to the settingsChanged() signal by using the
 * connectSettings() method.
 *
 * \note The methods are not thread-safe. For number/string formatting etc. the class is re-entrant. If one needs to have formatting in multiple threads it is suggested to create separate locales.
 */

class MLOCALE_EXPORT MLocale : public QObject
{
    Q_OBJECT
public:
    static void clearSystemDefault();

    /*!
     * Tells MLocale to use this factory to create config items
     *
     * A MLocaleAbstractConfigItem is an abstraction from the way
     * how MLocale gets and sets config values of the system.
     * These can be for example the current language or region of
     * the system. Users of the MLocale library can implement
     * a factory if needed. for an example look at the
     * MLocaleGConfConfigItemFactory.
     */
    static void setConfigItemFactory( const MLocaleAbstractConfigItemFactory* factory );

    /*!
     * \brief Returns the factory that is used to create config items.
     *
     * If there was no factory previously set or the factory is 0, a default
     * MLocaleNullConfigItemFactory is created upon the first call to this
     * function.
     */
    static const MLocaleAbstractConfigItemFactory* configItemFactory();

    /*!
     * \brief enum for Date formatting.
     *
     * This correlates closely with the <a
     * href="http://userguide.icu-project.org/formatparse/datetime#TOC-Producing-Normal-Date-Formats-for-a">
     * date type in ICU</a> and Unicode CLDR. The values
     * “DateShort”, “DateMedium”, “DateLong”, “DateFull”, have the same meaning
     * as the respective data types in ICU.
     * 
     * The value “DateYearAndMonth” is a libmeegotouch addition to
     * format only the year and the month without the
     * day. “DateYearAndMonth” implies “TimeNone”. For example in
     * Finnish locale the result of using “DateYearAndMonth” is
     * something like “Joulukuu 2011” whereas in Chinese locale the
     * result is something like “2011年 十二月”. This is useful
     * for something like a month view in calendar where a headline
     * showing the year and the month is needed but without the day
     * because the days are shown in a table below the headline.
     *
     *
     * The value “DateWeekdayAbbreviatedAndDayOfMonth” is a libmeegotouch
     * addition to format only the weekday name in abbreviated form
     * and the day of the month. For example in Finnish locale
     * the result of using “DateWeekdayAbbreviatedAndDayOfMonth” is
     * something like “ma 5” whereas in Chinese locale it is something
     * like “5日周一”.
     *
     * The value “DateWeekdayWideAndDayOfMonth” is also a libmeegotouch
     * addition, similar to “DateWeekdayAbbreviatedAndDayOfMonth”. It
     * uses a longer format of the weekday name. For example in Finnish
     * locale it would result in something like “maanantaina 5" whereas
     * in Chinese locale it is something like “5日星期一”.
     *
     * \sa MLocale::TimeType
     */
    enum DateType {
        DateNone,
        DateShort,
        DateMedium,
        DateLong,
        DateFull,
        DateYearAndMonth,
        DateWeekdayAbbreviatedAndDayOfMonth,
        DateWeekdayWideAndDayOfMonth
    };

    /*!
     * \brief enum for Time formatting.
     *
     * This correlates closely with the <a
     * href="http://userguide.icu-project.org/formatparse/datetime#TOC-Producing-Normal-Date-Formats-for-a">
     * time type in ICU</a> and Unicode CLDR
     *
     * \sa MLocale::DateType
     */
    enum TimeType {
        TimeNone,
        TimeShort,
        TimeMedium,
        TimeLong,
        TimeFull
    };

    // NOTE: could add LC_CTYPE, LC_PAPER, LC_ADDRESS, LC_TELEPHONE,
    // LC_MEASUREMENT, LC_IDENTIFICATION?

    //! Category type for the locale
    enum Category {MLcMessages, MLcTime, MLcCollate,
                   MLcNumeric, MLcMonetary, MLcName,
                   MLcTelephone
                  };

    //! Set of possible collations
    enum Collation {DefaultCollation, PhonebookCollation, PinyinCollation,
                    TraditionalCollation, StrokeCollation, DirectCollation,
                    PosixCollation, Big5hanCollation, Gb2312hanCollation
                   };

    //! Calendar type.
    enum CalendarType {DefaultCalendar, GregorianCalendar, IslamicCalendar,
                       ChineseCalendar, IslamicCivilCalendar, HebrewCalendar,
                       JapaneseCalendar, BuddhistCalendar, PersianCalendar,
                       CopticCalendar, EthiopicCalendar
                      };

    /*!
     * \brief Type to select 12 hour clock or 24 hour clock or default
     *
     * Chooses whether 12 hour clock or 24 hour clock should be forced
     * or whether the default for the current locale should be used.
     *
     * For example, the “en_US” locale uses a 12 hour clock by
     * default, i.e. in case of “en_US”, both
     * “LocaleDefaultTimeFormat24h“ and “TwelveHourTimeFormat24h”
     * will have the effect that a 12 hour clock is used.
     *
     * “TwentyFourHourTimeFormat24h” and “TwelveHourTimeFormat24h”
     * will force the use of a 24 hour clock or 12 hour clock, respectively,
     * no matter which one is used by default in this locale.
     */
    enum TimeFormat24h {LocaleDefaultTimeFormat24h,
                        TwelveHourTimeFormat24h,
                        TwentyFourHourTimeFormat24h};

    enum Weekday {Monday = 1, Tuesday, Wednesday, Thursday, Friday,
                  Saturday, Sunday
                 };

    /*!
     * \brief enum for weekday types
     *
     * \sa MLocale::Weekday
     */
    enum WeekdayType {
        WeekdayTypeWeekday,
        WeekdayTypeWeekend,
        WeekdayTypeWeekendOnset,
        WeekdayTypeWeekendCease
    };

    /*!
     * \brief Return type for MCollator::compare(). Denotes the order of two strings.
     */
    enum Comparison {LessThan = -1, Equal = 0, GreaterThan = 1};

    /*!
     * \brief Type to select the strength of an MCollator object
     *
     * For an explanation of the collation strengths see the
     * <a href="http://unicode.org/reports/tr10/">Unicode Collation
     * Algorithm</a>.
     */
    enum CollatorStrength {
        CollatorStrengthPrimary = 0,
        CollatorStrengthSecondary = 1,
        CollatorStrengthTertiary = 2,
        CollatorStrengthQuaternary = 3,
        CollatorStrengthIdentical = 15
    };

    /*!
     * \brief Type for locale dependent date symbol presentation
     *
     * Chooses whether the returned name should be stand-alone
     * or in context.
     *
     * Example:
     *
     * Using DateSymbolStandalone will select “sunnuntai” for Sunday
     * in Finnish language whereas DateSymbolFormat will select the
     * inflected form “sunnuntaina”.
     */
    enum DateSymbolContext {DateSymbolFormat, DateSymbolStandalone};

    /*!
     * \brief Length type for date symbol presentation
     *
     * Chooses how much the returned name should be abbreviated.
     *
     * Example:
     *
     * For the first day of the week in English language, using
     * DateSymbolAbbreviated will select “Sun”, using DateSymbolWide
     * will select “Sunday”, and using DateSymbolNarrow will select “S”.
     */
    enum DateSymbolLength {DateSymbolAbbreviated, DateSymbolWide, DateSymbolNarrow};

    /*!
     * \ brief Grouping formats for phone numbers
     * The phone number grouping specifies, how phone numbers will
     * be displayed to the user.
     * NoGrouping means that the phone numbers are not grouped at all.
     * NorthAmericanGrouping means that the phone numbers are grouped
     * according to the "North American Numbering Plan"
     * DefaultGrouping means that grouping is done according to the
     * current system settings.
     */
    enum PhoneNumberGrouping {
      DefaultPhoneNumberGrouping,
      NoPhoneNumberGrouping,
      NorthAmericanPhoneNumberGrouping
    };


    static MLocale *createSystemMLocale();

    /*!
     * \brief returns a "C" locale
     *
     * using this
     *
     * \code
     * MLocale locale = MLocale::createCLocale();
     * \endcode
     *
     * achieves the same as:
     *
     * \code
     * MLocale locale("en_US_POSIX");
     * \endcode
     *
     * libicu handles the string “en_US_POSIX” as synonym for
     * posix locale behaviour.
     */
    static MLocale createCLocale();

    /*!
     * \brief Constructs a MLocale as a copy of the current system default locale
     * \param parent the Object’s parent
     *
     * If MLocale is instantiated with this constructor, i.e.  without
     * the parameter specifying the locale name in ICU format as in the other
     * constructor
     * MLocale(const QString &localeName, QObject *parent), it will
     * return a copy of the system default locale, if this already
     * exists. If the system default locale does not exist yet, it is
     * created based on the global settings in the relevant gconf
     * keys. If the gconf settings are not available the system
     * default locale is created based on the contents of the LANG
     * environment variable.
     *
     * The copy of the system default locale created may already have a list
     * of translation catalogs installed, more translation catalogs
     * can be added using installTrCatalog().
     *
     * \sa MLocale(const QString &localeName, QObject *parent)
     * \sa installTrCatalog(const QString &name)
     * \sa setDefault(const MLocale &locale)
     *
     */
    explicit MLocale(QObject *parent = 0);

    /*!
     * \brief Constructs a MLocale from a ICU format locale ID string
     * \param localeName ICU format locale ID string.
     * \param parent the Object’s parent
     *
     * For details about ICU format locale ID strings
     * see http://userguide.icu-project.org/locale .
     *
     * <table border="1">
     * <caption>
     *   <big><b>
     *     Examples for ICU format locale ID strings
     *   </b></big>
     * </caption>
     * <tr>
     *   <th>Locale ID</th>
     *   <th>Language</th>
     *   <th>Script</th>
     *   <th>Country</th>
     *   <th>Variant</th>
     *   <th>Keywords</th>
     *   <th>Comment</th>
     * </tr>
     * <tr>
     *   <td>fi_FI</td>
     *   <td>fi</td>
     *   <td></td>
     *   <td>FI</td>
     *   <td></td>
     *   <td></td>
     *   <td>Finnish language in Finland, default sorting order</td>
     * <tr>
     *   <td>fi_FI\@collation=phonebook</td>
     *   <td>fi</td>
     *   <td></td>
     *   <td>FI</td>
     *   <td></td>
     *   <td>collation=phonebook</td>
     *   <td>Finnish language in Finland, phonebook sorting order</td>
     * </tr>
     * <tr>
     *   <td>zh_CN\@collation=stroke;calendar=chinese</td>
     *   <td>zh</td>
     *   <td></td>
     *   <td>CN</td>
     *   <td></td>
     *   <td>collation=stroke;calendar=chinese</td>
     *   <td>Simplified Chinese with sorting via stroke-count and Chinese calendar</td>
     * </tr>
     * </table>
     *
     * \sa MLocale(QObject *parent)
     */
    explicit MLocale(const QString &localeName, QObject *parent = 0);
    MLocale(const MLocale &other, QObject *parent = 0);

    virtual ~MLocale();

    MLocale &operator=(const MLocale &other);


    /*!
     * \brief Sets the default locale.
     */
    static void setDefault(const MLocale &locale);

    /*!
     * \brief Returns true if MLocale is valid and can be used
     */
    bool isValid() const;

    /*!
     * \brief Sets category with specified locale string
     * \param localeName ICU format locale ID string.
     */
    void setCategoryLocale(Category category, const QString &localeName);

    /*!
     * \brief Sets the collation mode
     */
    void setCollation(Collation collation);

    /*!
     * \brief Returns the collation mode
     */
    Collation collation() const;

    /*!
     * \brief Sets calendar type
     */
    void setCalendarType(CalendarType calendar);

    /*!
     * \brief Returns calendar type
     */
    CalendarType calendarType() const;

    /*!
     * \brief Sets whether 24 hour clock, 12 hour clock or default is used
     *
     * \param timeFormat24h enum to choose the 12/24 hour mode
     *
     * If MLocale::TwelveHourTimeFormat24h is given as the parameter
     * the locale is forced to use 24 hour mode, if
     * MLocale::TwentyFourHourTimeFormat24h is given as the parameter
     * the locale is forced to use 12 hour mode.
     * If MLocale::LocaleDefaultTimeFormat24 is given as the parameter
     * the locale is neither forced to use 12 nor 24 hour mode,
     * it uses the default for this locale then.
     *
     * \sa timeFormat24h() const
     * \sa defaultTimeFormat24h() const
     */
    void setTimeFormat24h(TimeFormat24h timeFormat24h);

    /*!
     * \brief Returns whether 24 hour clock, 12 hour clock or default is used
     *
     * returns MLocale::TwelveHourTimeFormat24h if 12 hour mode
     * is forced for this locale,
     * returns MLocale::TwentyFourHourTimeFormat24h if 24 hour mode
     * is forced for this locale and returns
     * MLocale::LocaleDefaultTimeFormat24h if the 12/24 hour mode
     * is not forced but left to what this locale would use by default.
     *
     * \sa setTimeFormat24h(TimeFormat24h timeFormat24h)
     * \sa defaultTimeFormat24h() const
     */
    TimeFormat24h timeFormat24h() const;

    /*!
     * \brief Returns whether 24 hour or 12 hour format is used by default
     *
     * returns MLocale::TwelveHourTimeFormat24h if this locale would use
     * 12 hour mode by default and MLocale::TwentyFourHourTimeFormat24h
     * if this locale would use 24 hour mode by default.
     *
     * Actually this locale may use a different mode because
     * the default can be overridden, this method shows only
     * what the default would be if it were not overridden.
     *
     * \sa timeFormat24h() const
     * \sa setTimeFormat24h(TimeFormat24h timeFormat24h)
     */
    TimeFormat24h defaultTimeFormat24h() const;

    /*!
     * \brief Returns a MCollator which compares QStrings based on language/country/collation rules
     */
    MCollator collator() const;

    /*!
     * \brief locale-aware and context-sensitive conversion to lowercase
     * \param string the string to convert to lowercase
     *
     * returns the lowercased string.
     *
     * Use this instead of QString::toLower() if locale-aware and context-sensitive
     * conversion to lowercase is required.
     *
     * This is implemented using libicu, if libmeegotouch is compiled
     * without libicu, QString::toLower() is used as a fallback.
     *
     * <a
     * href="http://doc.qt.nokia.com/qstring.html#toLower">QString::toLower()</a>
     * is <b>not</b> locale-aware and not context-sensitive,
     * i.e. neither the locale nor the context influence its
     * behaviour.
     *
     * Therefore, it does not work correctly for Greek, where the
     * character "Σ" (capital sigma) lowercases to either "ς" (small
     * final sigma) or "σ" (small sigma) depending on whether the
     * capital sigma is the last letter in a word. (It is
     * context-dependent.)
     *
     * Neither does it work for Lithuanian and Turkic languages where
     * a “combining dot above” character may need to be removed in
     * certain cases. (It “contracts” and is language- and
     * context-dependent.)
     *
     * For details see <a
     * href="http://unicode.org/reports/tr21/">Unicode Case
     * Mappings</a>.
     *
     * \sa toUpper()
     */
    QString toLower(const QString &string) const;

    /*!
     * \brief locale-aware, context-sensitive conversion to uppercase
     * \param string the string to convert to uppercase
     *
     * returns the uppercased string.
     *
     * Use this instead of QString::toUpper() if locale-aware and
     * context-sensitive conversion to lowercase is required.
     *
     * This is implemented using libicu, if libmeegotouch is compiled
     * without libicu, QString::toUpper() is used as a fallback.
     *
     * <a
     * href="http://doc.qt.nokia.com/qstring.html#toUpper">QString::toUpper()</a>
     * is <b>not</b> locale-aware and not context-sensitive,
     * i.e. neither the locale nor the context influence its
     * behaviour.
     *
     * \sa toLower()
     */
    QString toUpper(const QString &string) const;

    /*!
     * \brief Returns the endonym of the language of the locale
     *
     * The language <a href="http://en.wikipedia.org/wiki/Endonym">endonym</a> is the
     * name of the language which is used by the native speakers of
     * this language.
     *
     * <table border="1">
     * <caption>
     *  <big><b>Examples for language endonyms</b></big>
     * </caption>
     * <tr>
     *    <th>English exonym</th><th>Language endonym</th>
     * </tr>
     * <tr>
     *    <td>German</td><td>Deutsch</td>
     * </tr>
     * <tr>
     *    <td>Russian</td><td>русский язык</td>
     * </tr>
     * <tr>
     *    <td>Japanese</td><td>日本語</td>
     * </tr>
     * </table>
     *
     */
    QString languageEndonym() const;

    /*!
     * \brief Returns the endonym of the country of the locale
     *
     * The country <a href="http://en.wikipedia.org/wiki/Endonym">endonym</a>
     * is the name of the country which is used by the inhabitants of that country.
     *
     * <table border="1">
     * <caption>
     *  <big><b>Examples for country endonyms</b></big>
     * </caption>
     * <tr>
     *    <th>English exonym</th><th>Language endonym</th>
     * </tr>
     * <tr>
     *    <td>Germany</td><td>Deutschland</td>
     * </tr>
     * <tr>
     *    <td>Russia</td><td>Россия</td>
     * </tr>
     * <tr>
     *    <td>Japan</td><td>日本</td>
     * </tr>
     * </table>
     *
     */
    QString countryEndonym() const;

    /*!
     * \brief returns the decimal point character of this locale.
     */
    QString decimalPoint() const;

    /*!
     * \brief join a list of strings according to the conventions of the locale
     *
     * \param texts the texts to be joined
     *
     * This method is intended to join a list of strings with commas
     * according to the conventions of the locale. For example, if you
     * want to join a list of names like
     *
     * “John Doe”, “Judy Roe”, “James Doe”
     *
     * the result might be “John Doe, Judy Roe, James Doe” in
     * English and many other locales, but for example in Arabic locales
     * or Chinese locales, different versions of the comma may be used.
     *
     * On top of that, if the list contains both texts in
     * left-to-right scripts <b>and</b> texts right-to-left scripts,
     * texts which have a different direction then the firsts text
     * maybe reordered strangely if all texts are only joined with
     * some separator. Especially if the texts to be joined contain
     * symbols, for example parentheses, weird bidi reordering may
     * happen. To prevent nonsensical bidi reordering, the direction
     * of each text in the list is checked and directional markers
     * are inserted to make sure each individual text is reordered
     * correctly.
     */
    QString joinStringList(const QStringList &texts) const;

    /*!
     * \brief Returns the list of scripts used by the locale
     *
     * This returns the scripts used by the locale, in form of <a
     * href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO
     * 15924 script codes</a>. Most locales use only one script
     * but there are a few locales which use several scripts.
     *
     * <table border="1">
     * <caption>
     *  <big><b>Examples for script codes</b></big>
     * </caption>
     * <tr>
     *    <th>locale name</th><th>script codes</th>
     * </tr>
     * <tr>
     *    <td>en_US</td><td>Latn</td>
     * </tr>
     * <tr>
     *    <td>sr_RS</td><td>Cyrl</td>
     * </tr>
     * <tr>
     *    <td>sr_Cyrl_RS</td><td>Cyrl</td>
     * </tr>
     * <tr>
     *    <td>sr_Latn_RS</td><td>Latn</td>
     * </tr>
     * <tr>
     *    <td>zh_Hant_TW</td><td>Hani, Bopo</td>
     * </tr>
     * <tr>
     *    <td>ja_JP</td><td>Kana, Hira, Hani</td>
     * </tr>
     * </table>
     *
     */
    QStringList localeScripts() const;

    /*!
     * \brief Returns a list of character or strings to be used in indices
     *
     * This returns an QStringList of characters (or character
     * sequences) which can be used as index characters in user
     * interfaces. Which index characters are useful depends on the
     * locale set in lc_collation as the collation (sorting) rules
     * depend on the locale.
     *
     * For example, if lc_collation is set to Czech locale (i.e. if
     * MLocale::categoryName(MLocale::MLcCollate) returns “cs_CZ”)
     * this will return a list like:
     *
     *     “A B C Č D E F G H CH I J K L M N O P Q R Ř S Š T U V W X Y Z Ž”
     *
     * Note that this also contains the character sequence “CH” as
     * an index “character” because in Czech CH is sorted as if it
     * were a single character after H. Therefore, CH deserves its own
     * entry in a collation index for Czech.
     *
     * For more details about such index characters see:
     * <a href="http://www.unicode.org/reports/tr35/#Character_Elements">
     *
     */
    QStringList exemplarCharactersIndex() const;

    /*!
     * \brief Returns the name of an appropriate sort bucket for a string
     *
     * This function is useful to get index titles when sorting a large
     * amount of strings like in a telephone book, a list of videos etc.
     * The list of useful index titles is language specific, for example
     * for Czech (“cs_CZ” locale) it is
     *
     *    “A B C Č D E F G H CH I J K L M N O P Q R Ř S Š T U V W X Y Z Ž”
     *
     * for Japanese (“ja_JP@collation=standard” locale, same as “ja_JP”) it is
     *
     *    “あ か さ た な は ま や ら わ”
     *
     * and for traditional Chinese (“zh_TW@collation=stroke”, same as “zh_TW”) locale it is
     *
     *    “一 丁 三 丑 丙 丞 串 並 亟 乘 乾 傢 亂 僧 億 儒 優 叢 嚥 勸 儷 儼 囌 囑 廳”
     *
     * This function is helpful to find out which bucket a string will be
     * sorted into when sorting locale aware.
     *
     * Examples for “cs_CZ” locale:
     *
     * <table border="1">
     * <caption>
     *   <big><b>
     *     Strings to sort and buckets for “cs_CZ” locale
     *   </b></big>
     * </caption>
     * <tr>
     *   <th>String</th>
     *   <th>Bucket</th>
     * </tr>
     * <tr>
     *   <td>cesta</td>
     *   <td>C</td>
     * </tr>
     * <tr>
     *   <td>češtinǎ</td>
     *   <td>Č</td>
     * </tr>
     * <tr>
     *   <td>chemie</td>
     *   <td>CH</td>
     * </tr>
     * <tr>
     *   <td>ů</td>
     *   <td>U</td>
     * </tr>
     * <tr>
     *   <td>α</td>
     *   <td>Α</td>
     * </tr>
     * <tr>
     *   <td>Α</td>
     *   <td>Α</td>
     * </tr>
     * <tr>
     *   <td>沙紀</td>
     *   <td>沙</td>
     * </tr>
     * </table>
     *
     * Examples for “ja_JP@collation=standard” locale:
     *
     * <table border="1">
     * <caption>
     *   <big><b>
     *     Strings to sort and buckets for “ja_JP@collation=standard” locale
     *   </b></big>
     * </caption>
     * <tr>
     *   <th>String</th>
     *   <th>Bucket</th>
     * </tr>
     * <tr>
     *   <td>richard</td>
     *   <td>R</td>
     * </tr>
     * <tr>
     *   <td>さき</td>
     *   <td>さ</td>
     * </tr>
     * <tr>
     *   <td>ジョン</td>
     *   <td>さ</td>
     * </tr>
     * <tr>
     *   <td>はなこ</td>
     *   <td>は</td>
     * </tr>
     * </table>
     *
     * Examples for “zh_TW@collation=stroke” locale:
     *
     * <table border="1">
     * <caption>
     *   <big><b>
     *     Strings to sort and buckets for “zh_TW@collation=stroke” locale
     *   </b></big>
     * </caption>
     * <tr>
     *   <th>String</th>
     *   <th>Bucket</th>
     * </tr>
     * <tr>
     *   <td>John</td>
     *   <td>J</td>
     * </tr>
     * <tr>
     *   <td>宁驰</td>
     *   <td>丙</td>
     * </tr>
     * <tr>
     *   <td>柳 君蘅</td>
     *   <td>亟</td>
     * </tr>
     * </table>
     *
     * As can be seen in the above examples, this function tries to
     * return useful extra buckets for strings which sort out of the
     * range of the bucket list of the language of the current locale.
     * For example if one is running in Czech locale but has also some
     * Japanese and some Greek names in the contact list these foreign
     * strings sort outside of the range of the Czech bucket list.
     * This function tries to create useful extra buckets for these
     * foreign strings.
     *
     * For applications using an MAbstractItemModel, it is probably more
     * convenient to use the MLocaleBuckets class that uses this function
     * internally.
     *
     * \sa MLocaleBuckets
     * \sa exemplarCharactersIndex()
     * \sa indexBucket(const QString &str, const QStringList &buckets, const MCollator &collator)
     */
    QString indexBucket(const QString &str) const;
    
    /*!
     * \brief Internal version of MLocale::indexBucket().
     *
     * \param str String to find a bucket for
     * \param buckets bucket list (result of MLocale::exemplarCharactersIndex())
     * \param collator collator to use for sorting.
     *
     * This overloaded function is more efficient if a large number of index
     * buckets is to be retrieved since it can re-use the buckets list and the
     * collator from one call to the next. Before the first call, initialize
     * the 'buckets' list with MLocale::exemplarCharactersIndex().
     *
     * On top of that, please take care to set the strength of the collator
     * passed as an argument to primary strength, if this is not done the
     * resulting buckets will be slightly wrong.
     *
     * But use primary strength only for the collator used to get the
     * buckets, not for the collator used to do the actual
     * sorting. The collator used to do the actual sorting should be
     * set to quaternary strength in most cases.
     *
     * For an explanation of the collation strengths see the <a
     * href="http://unicode.org/reports/tr10/">Unicode Collation
     * Algorithm</a>.
     *
     * Example:
     * \code
     * MLocale locale; // gets the current system default locale
     * MCollator collator = locale.collator();
     * // IMPORTANT: don’t forget to set the collator for the buckets to
     * // primary strength:
     * collator.setStrength(MLocale::CollatorStrengthPrimary);
     * QStringList buckets = locale.exemplarCharactersIndex();
     * // now you can find the index bucket for a name, for example
     * // in case of “Abraham”, the bucket will be “A” in “en_US” locale and most
     * // other locales.
     * QString bucket = indexBucket(QString::fromUtf8("Abraham"), buckets, collator);
     * \endcode
     *
     * \sa indexBucket(const QString &str)
     */
    QString indexBucket(const QString &str, const QStringList &buckets, const MCollator &collator) const;

    /*!
     * \brief Returns the language code of the locale in ISO-639 format
     *
     * If the language code cannot be parsed out of the locale name
     * an empty string is returned.
     *
     * Example:
     * If the locale name is “fi_FI”, this will return “fi”.
     *
     * \sa name()
     * \sa script()
     * \sa country()
     * \sa variant()
     */
    QString language() const;

    /*!
     * \brief Returns the country code of the locale in ISO-3166 format
     *
     * If the country code cannot be parsed out of the locale name
     * an empty string is returned.
     *
     * Example:
     * If the locale name is “fi_FI” this will return “FI”.
     * If the locale name is “es_419” this will return “419”.
     * “419” is the generic code for Latin American Spanisch.
     * This “es_419” is used in the translations to have one
     * common translation for all Latin American locales instead
     * of individual ones like for all locales like “es_MX”.
     *
     * \sa name()
     * \sa language()
     * \sa script()
     * \sa variant()
     */
    QString country() const;

    /*!
     * \brief Returns the script code of the locale in ISO-15924 format
     *
     * Returns the part of the locale name which specifies the script
     * in form of <a
     * href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO
     * 15924 script codes</a>
     *
     * If that part of the locale name was not specified, i.e. if the
     * default script for that language and country is used, it
     * returns an empty string. For example, if the locale name is
     * “ru_RU”, an empty string is returned and not “Cyrl” which
     * is the <a
     * href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO
     * 15924 code</a> of the Cyrillic script used by the “ru_RU”
     * locale.
     *
     * If you need to find out which scripts are used by a certain locale
     * use localeScripts() const instead.
     *
     * \sa name()
     * \sa language()
     * \sa country()
     * \sa variant()
     * \sa localeScripts() const
     */
    QString script() const;

    /*!
     * \brief Returns the variant of the locale
     *
     * If the variant code cannot be parsed out of the locale name
     * an empty string is returned.
     *
     * Example:
     * If the locale name is <code>sr_Latn_RS_REVISED\@currency=USD</code>
     * this will return <code>REVISED</code>.
     *
     * \sa name()
     * \sa language()
     * \sa script()
     * \sa country()
     */
    QString variant() const;

    /*!
     * \brief Returns the string representation of the locale
     *
     * The string representation of the locale is the full ICU locale
     * ID string. See the <a
     * href="http://userguide.icu-project.org/locale">ICU user
     * guide</a> for examples.
     *
     * \sa language()
     * \sa script()
     * \sa country()
     * \sa variant()
     */
    QString name() const;

    /*!
     * \brief Returns the text direction of the locale
     *
     * This function unfortunately has a confusing name, it is not the
     * direction of a certain amount of text, which is detected by
     * directionForText(const QString &text). For a purely Arabic text
     * for example, directionForText() will always return
     * Qt::RightToLeft no matter what the current locale is (it is a
     * static function, thus independent of the current locale, the
     * result only depends on th text given as an argument).
     *
     * This function here actually returns the <b>layout direction</b>
     * for the current locale.
     *
     * The layout direction of the QApplication is set to what
     * textDirection() returns for the system default locale
     * (which can be set with setDefault(const MLocale &locale)).
     *
     * The layout direction returned here used to be Qt::RightToLeft
     * for locales which use RTL scripts (e.g. Arabic, Hebrew, ...)
     * and Qt::LeftToRight for locales which use LTR scripts (e.g.
     * English, Chinese, Russian, ...)
     *
     * Now this has changed because it has been requested to disable
     * layout reversal by default, therefore this function will
     * <b>always</b> return Qt::LeftToRight by default now, even for
     * locales with RTL scripts like Arabic or Hebrew.
     *
     * This new behaviour can be overridden by setting the option
     * “layout-direction” in the full locale name.
     * “layout-direction=rtl” forces right-to-left layout direction
     * “layout-direction=ltr” forces left-to-right layout direction
     * and “layout-direction=auto” sets the layout direction to the
     * direction of the script used by the locale, i.e.
     * “layout-direction=auto” reproduces the previous behaviour.
     *
     * Examples:
     *
     * <table border="1">
     * <caption>
     *   <big><b>
     *      Examples for locale names and layout reversal behaviour
     *   </b></big>
     * </caption>
     * <tr>
     *   <th>Locale ID</th>
     *   <th>textDirection()</th>
     *   <th>defaultLayoutDirection()</th>
     * </tr>
     * <tr>
     *   <td>ar_EG</td>
     *   <td>Qt::LeftToRight</td>
     *   <td>Qt::LeftToRight</td>
     * </tr>
     * <tr>
     *   <td>ar_EG\@layout-direction=ltr</td>
     *   <td>Qt::LeftToRight</td>
     *   <td>Qt::LeftToRight</td>
     * </tr>
     * <tr>
     *   <td>ar_EG\@layout-direction=rtl</td>
     *   <td>Qt::RightToLeft</td>
     *   <td>Qt::RightToLeft</td>
     * </tr>
     * <tr>
     *   <td>ar_EG\@layout-direction=auto</td>
     *   <td>Qt::RightToLeft</td>
     *   <td>Qt::LayoutDirectionAuto</td>
     * </tr>
     * <tr>
     *   <td>en_US</td>
     *   <td>Qt::LeftToRight</td>
     *   <td>Qt::LeftToRight</td>
     * </tr>
     * <tr>
     *   <td>en_US\@layout-direction=ltr</td>
     *   <td>Qt::LeftToRight</td>
     *   <td>Qt::LeftToRight</td>
     * </tr>
     * <tr>
     *   <td>en_US\@layout-direction=rtl</td>
     *   <td>Qt::RightToLeft</td>
     *   <td>Qt::RightToLeft</td>
     * </tr>
     * <tr>
     *   <td>en_US\@layout-direction=auto</td>
     *   <td>Qt::LeftToRight</td>
     *   <td>Qt::LayoutDirectionAuto</td>
     * </tr>
     * </table>
     *
     * \sa defaultLayoutDirection()
     * \sa directionForText()
     * \sa setDefault(const MLocale &locale)
     */
    Qt::LayoutDirection textDirection() const;

    /*!
     * \brief Returns the language code of the locale category in ISO-639 format
     *
     * same as language(), only for a specific category.
     *
     * \sa categoryName()
     * \sa categoryScript()
     * \sa categoryCountry()
     * \sa categoryVariant()
     * \sa name()
     * \sa language()
     * \sa script()
     * \sa country()
     * \sa variant()
     */
    QString categoryLanguage(Category category) const;

    /*!
     * \brief Returns the country code of the locale category in ISO-3166 format
     *
     * same as country(), only for a specific category.
     *
     * \sa categoryName()
     * \sa categoryLanguage()
     * \sa categoryScript()
     * \sa categoryVariant()
     * \sa name()
     * \sa language()
     * \sa script()
     * \sa country()
     * \sa variant()
     */
    QString categoryCountry(Category category) const;

    /*!
     * \brief Returns the script code of the locale category in ISO-15924 format
     *
     * same as script(), only for a specific category.
     *
     * Returns the part of the locale category name which specifies the script
     * in form of <a
     * href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO
     * 15924 script codes</a>
     *
     * If that part of the locale category name was not specified, i.e. if the
     * default script for that language and country is used, it
     * returns an empty string. For example, if the locale category name is
     * “ru_RU”, an empty string is returned and not “Cyrl” which
     * is the <a
     * href="http://www.unicode.org/iso15924/iso15924-codes.html">ISO
     * 15924 code</a> of the Cyrillic script used by the “ru_RU”
     * locale.
     *
     * If you need to find out which scripts are used by a certain locale
     * use localeScripts() const instead.
     *
     * \sa categoryName()
     * \sa categoryLanguage()
     * \sa categoryCountry()
     * \sa categoryVariant()
     * \sa localeScripts() const
     * \sa name()
     * \sa language()
     * \sa script()
     * \sa country()
     * \sa variant()
     */
    QString categoryScript(Category category) const;

    /*!
     * \brief Returns the variant of the locale category
     *
     * same as variant(), only for a specific category.
     *
     * \sa categoryName()
     * \sa categoryLanguage()
     * \sa categoryScript()
     * \sa categoryCountry()
     * \sa name()
     * \sa language()
     * \sa script()
     * \sa country()
     * \sa variant()
     */
    QString categoryVariant(Category category) const;

    /*!
     * \brief Returns the string representation of the locale category
     *
     * same as name(), only for a specific category.
     *
     * The string representation of the locale category is the full ICU locale
     * ID string. See the <a
     * href="http://userguide.icu-project.org/locale">ICU user
     * guide</a> for examples.
     *
     * \sa categoryLanguage()
     * \sa categoryScript()
     * \sa categoryCountry()
     * \sa categoryVariant()
     * \sa name()
     * \sa language()
     * \sa script()
     * \sa country()
     * \sa variant()
     */
    QString categoryName(Category category) const;

    /*!
     * \brief Returns the string representation of a number
     * \param i number to format
     *
     * \sa formatNumber(short i) const
     * \sa formatNumber(int i) const
     * \sa formatNumber(float i) const
     * \sa formatNumber(double i, int precision) const
     */
    QString formatNumber(qlonglong i) const;

    /*!
     * \brief Returns the qlonglong represented by a localized string
     * \param s localized string to parse
     * \param ok pointer to a bool indicating success or failure
     *
     * If ok is not NULL, reports failure by setting *ok to false and
     * success by setting *ok to true.
     *
     * \sa formatNumber(qlonglong i) const
     */
    qlonglong toLongLong(const QString &s, bool *ok = 0) const;

    /*!
     * \brief Returns the string representation of a number
     * \param i number to format
     *
     * \sa formatNumber(qlonglong i) const
     * \sa formatNumber(int i) const
     * \sa formatNumber(double i, int precision) const
     * \sa formatNumber(float i) const
     */
    QString formatNumber(short i) const;

    /*!
     * \brief Returns the short represented by a localized string
     * \param s localized string to parse
     * \param ok pointer to a bool indicating success or failure
     *
     * If ok is not NULL, reports failure by setting *ok to false and
     * success by setting *ok to true.
     *
     * \sa formatNumber(short i) const
     */
    short toShort(const QString &s, bool *ok = 0) const;

    /*!
     * \brief Returns the string representation of a number
     * \param i number to format
     *
     * \sa formatNumber(qlonglong i) const
     * \sa formatNumber(short i) const
     * \sa formatNumber(double i, int precision) const
     * \sa formatNumber(float i) const
     */
    QString formatNumber(int i) const;

    /*!
     * \brief Returns the int represented by a localized string
     * \param s localized string to parse
     * \param ok pointer to a bool indicating success or failure
     *
     * If ok is not NULL, reports failure by setting *ok to false and
     * success by setting *ok to true.
     *
     * \sa formatNumber(int i) const
     */
    int toInt(const QString &s, bool *ok = 0) const;

    /*!
     * \brief Returns the string representation of a number
     * \param i number to format
     * \param maxPrecision maximum number of fractional digits
     *
     * This just calls formatNumber(i, maxPrecision, 0).
     *
     * \sa formatNumber(qlonglong i) const
     * \sa formatNumber(short i) const
     * \sa formatNumber(int i) const
     * \sa formatNumber(float i) const
     */
    QString formatNumber(double i, int maxPrecision = -1) const;

    /*!
     * \brief Returns the string representation of a number
     * \param i number to format
     * \param maxPrecision maximum number of fractional digits
     * \param minPrecision minimum number of fractional digits
     *
     * minPrecision is bound to be between 0 and maxPrecision
     * inclusive.
     *
     * \sa formatNumber(qlonglong i) const
     * \sa formatNumber(short i) const
     * \sa formatNumber(int i) const
     * \sa formatNumber(float i) const
     */
    QString formatNumber(double i, int maxPrecision, int minPrecision) const;

    /*!
     * \brief Returns the double represented by a localized string
     * \param s localized string to parse
     * \param ok pointer to a bool indicating success or failure
     *
     * If ok is not NULL, reports failure by setting *ok to false and
     * success by setting *ok to true.
     *
     * \sa formatNumber(double i, int precision) const
     */
    double toDouble(const QString &s, bool *ok = 0) const;

    /*!
     * \brief Returns the string representation of a number
     * \param i number to format
     *
     * Examples:
     *
     * \code
     * // format a number to a string according to the conventions of the
     * // current system default locale:
     * MLocale locale;  // gets the current system default locale
     * QString numberString = locale.formatNumber(12345670.89);
     * \endcode
     *
     * \code
     * // format a number to a string using US English conventions no
     * // matter what the current system default locale is:
     * MLocale locale("en_US");
     * QString numberString = locale.formatNumber(12345670.89);
     * // now numberString contains “12,345,670.89”
     * \endcode
     *
     * \code
     * // format a number to a string using Arabic conventions no
     * // matter what the current system default locale is:
     * MLocale locale("ar");
     * QString numberString = locale.formatNumber(12345670.89);
     * // now numberString contains: “١٢٬٣٤٥٬٦٧٠٫٨٩”
     * \endcode
     *
     * \sa formatNumber(qlonglong i) const
     * \sa formatNumber(short i) const
     * \sa formatNumber(int i) const
     * \sa formatNumber(double i, int precision) const
     */
    QString formatNumber(float i) const;

    /*!
     * \brief Returns the float represented by a localized string
     * \param s localized string to parse
     * \param ok pointer to a bool indicating success or failure
     *
     * If ok is not NULL, reports failure by setting *ok to false and
     * success by setting *ok to true.
     *
     * \sa formatNumber(float i) const
     */
    float toFloat(const QString &s, bool *ok = 0) const;

    /*!
     * \brief Returns the string representation of a number as percentage
     * \param i number to format
     * \param decimals number of digits shown after decimal separator
     *
     * Example:
     *
     * \code
     * MLocale locale; // gets the current system default locale
     * QString percentString = locale.formatPercent(0.0123, 2);
     * \endcode
     *
     * <table border="1">
     * <caption>
     *  <big><b>Examples of formatPercent results</b></big>
     * </caption>
     * <tr>
     *  <th>locale</th><th>double value</th><th>decimals</th><th>result</th>
     * </tr>
     * <tr>
     *   <td>en_US</td><td>0.0123</td><td>2</td><td>1.23%</td>
     * </tr>
     * <tr>
     *   <td>en_US</td><td>12.3456789</td><td>4</td><td>1,234.5679%</td>
     * </tr>
     * <tr>
     *   <td>de_CH</td><td>12.3456789</td><td>4</td><td>1'234.5679%</td>
     * </tr>
     * <tr>
     *   <td>tr_TR</td><td>12.3456789</td><td>4</td><td>% 1.234,5679</td>
     * </tr>
     * </table>
     */
    QString formatPercent(double i, int decimals = 0) const;

    /*!
     * \brief Formats an amount of currency
     * \param amount amount to format
     * \param currency three letter currency code in ISO-4217 format, e.g. EUR or USD
     */
    QString formatCurrency(double amount, const QString &currency) const;

    /*!
     * \brief Creates a string presentation for a date time with explicit format lengths
     * \param dateTime time object to create representation from
     * \param dateType style of date formatting
     * \param timeType style of time formatting
     * \param calendarType calendar type to use for formatting
     *
     * If dateType is MLocale::DateNone <b>and</b> timeType is MLocale::TimeNone,
     * an empty string is returned.
     *
     * Using this can be considerably slower than using
     * formatDateTime(const MCalendar &mCalendar, DateType datetype = DateLong, TimeType timetype = TimeLong) const,
     * see the example there.
     *
     * \sa formatDateTime(const MCalendar &mCalendar, DateType datetype = DateLong, TimeType timetype = TimeLong) const
     */
    QString formatDateTime(const QDateTime &dateTime, DateType dateType = DateLong,
                           TimeType timeType = TimeLong,
                           CalendarType calendarType = DefaultCalendar) const;

    /*!
     * \brief String presentation with explicit calendar type
     * \param dateTime time to format
     * \param calendarType calendar to use
     *
     * This uses the TimeLong and DateLong formats.
     *
     * Using this can be considerably slower than using
     * formatDateTime(const MCalendar &mCalendar, DateType datetype = DateLong, TimeType timetype = TimeLong) const,
     * see the example there.
     *
     * \sa formatDateTime(const QDateTime &dateTime, DateType dateType = DateLong, TimeType timeType = TimeLong, CalendarType calendarType = DefaultCalendar) const
     * \sa formatDateTime(const MCalendar &mCalendar, DateType datetype = DateLong, TimeType timetype = TimeLong) const
     */
    QString formatDateTime(const QDateTime &dateTime, CalendarType calendarType) const;

    /*!
     * \brief Formats MCalendar using its native calendar system
     * \param mCalendar Calendar holding the datetime to format
     * \param datetype format for date
     * \param timetype format for time
     *
     * If dateType is MLocale::DateNone <b>and</b> timeType is
     * MLocale::TimeNone, an empty string is returned.
     *
     * The return value of this method does not necessarily start with
     * an uppercase letter because it cannot know in which context the
     * returned string will be used. Therefore, it is left
     * to the application to uppercase the first letter if the
     * context requires is. Uppercasing the first letter could
     * be done as in the following example:
     *
     * \code
     * QString formattedDateTime;
     * QDateTime current = QDateTime::currentDateTime();
     * MLocale locale;
     * MCalendar calendar;
     * calendar.setDateTime(current);
     * formattedDateTime = locale.formatDateTime(calendar, MLocale::DateMedium, MLocale::TimeMedium);
     * // Make the first letter uppercase:
     * if (!formattedDateTime.isEmpty())
     *    formattedDateTime[0] = locale.toUpper(formattedDateTime.at(0))[0];
     * \endcode
     *
     * If many dates and times need to be formatted, this method
     * should be preferred over
     * formatDateTime(const QDateTime &dateTime, DateType dateType = DateLong, TimeType timeType = TimeLong, CalendarType calendarType = DefaultCalendar) const
     * because the latter one creates an MCalendar and sets it to the QDateTime.
     * It is wasteful to create a new MCalendar many times, it is better
     * to create the MCalendar only once, change the date and time of this
     * calendar as needed and use this MCalendar for formatting.
     * Example:
     *
     * \code
     * QString formattedDateTime;
     * QDateTime current = QDateTime::currentDateTime();
     * MLocale locale;
     * MCalendar calendar;
     * for(int i=0 ; i < 5000 ; i++) {
     *     current.addSecs(36);
     *     calendar.setDateTime(current);
     *     formattedDateTime = locale.formatDateTime(calendar, MLocale::DateMedium, MLocale::TimeMedium);
     * }
     * \endcode
     *
     * \sa formatDateTime(const QDateTime &dateTime, DateType dateType = DateLong, TimeType timeType = TimeLong, CalendarType calendarType = DefaultCalendar) const
     * \sa formatDateTime(const QDateTime &dateTime, CalendarType calendarType) const
     */
    QString formatDateTime(const MCalendar &mCalendar, DateType datetype = DateLong,
                           TimeType timetype = TimeLong) const;

    QString formatDateTimeICU(const QDateTime &dateTime,
                              const QString &formatString) const;
    QString formatDateTimeICU(const MCalendar &mCalendar,
                              const QString &formatString) const;
    /*!
     * \brief creates a string presentation for a QDateTime with specific format string
     * \param dateTime QDateTime to format
     * \param formatString in ISO-14652 date time format
     *
     * \sa formatDateTime(const MCalendar &mCalendar, const QString &formatString) const
     */
    QString formatDateTime(const QDateTime &dateTime,
                           const QString &formatString) const;
    // divergence: not implemented modified field descriptors (%Ec, %EC, %EY etc)

    /*!
    \brief Formats a date string based on ISO-14652 (draft) pattern

    \sa formatDateTime(const QDateTime &dateTime, const QString &formatString) const;

    For more information about the format characters used here see
    <a href="http://www.open-std.org/jtc1/SC22/WG20/docs/n972-14652ft.pdf">
    ISO-14652 (draft)
    </a>
    or
    <a href="http://linux.die.net/man/1/date">
    the man page of “date”
    </a>
    or
    <a href="http://www.gnu.org/s/libc/manual/html_node/Formatting-Calendar-Time.html">
    the documentation of the glibc function “strftime”
    </a>.

    The pattern may contain the following symbols to be replaced with
    the corresponding information:
     - \%a FDCC-set’s abbreviated weekday name.
     - \%A FDCC-set’s stand-alone full weekday name.
           “stand-alone” means that for example for “Thursday” in Finnish “torstai”
           is returned and not the inflected form “torstaina”.
     - \%b FDCC-set’s abbreviated month name.
     - \%B FDCC-set’s stand-alone full month name.
           “stand-alone” means that for example for “Oktober” in Finnish “lokakuu”
           is returned and not the inflected form “lokakuuta”.
     - \%c FDCC-set’s appropriate date and time representation.
     - \%C Century (a year divided by 100 and truncated to integer) as decimal number (00-99).
     - \%d Day of the month as a decimal number (01-31).
     - \%D Date in the format mm/dd/yy.
     - \%e Day of the month as a decimal number (1-31 in at two-digit field with leading &lt;space&gt; fill).
     - \%F The date in the format YYYY-MM-DD (An ISO 8601 format).
     - \%g Week-based year within century, as a decimal number (00-99).
     - \%G Week-based year with century, as a decimal number (for example 1997).
     - \%h A synonym for %b.
     - \%H Hour (24-hour clock), as a decimal number (00-23).
     - \%I Hour (12-hour clock), as a decimal number (01-12).
     - \%j Day of the year, as a decimal number (001-366).
     - \%m Month, as a decimal number (01-13).
     - \%M Minute, as a decimal number (00-59).
     - \%n A &lt;newline&gt; character.
     - \%p FDCC-set’s equivalent of either AM or PM.
     - \%r locale specific 12-hour clock time using the AM/PM notation
           Similar to “%I:%M %p” but the exact format does depend more on
           the locale. E.g. for “en_GB” locale the result may look like
           “12:15 PM” with a colon between the hours and he minutes whereas
           for “fi_FI” locale a dot may be used as the separator, like
           “12.15 ip.”. The exact result depends on how the TimeShort format
           for the locale is implemented in ICU.
     - \%R locale specific 24-hour clock time.
           Similar to “%H:%M” but the exact format depends on the locale.
           E.g. for “en_GB” locale the result may look like “14:15” and
           for “fi_FI” locale the result may look like “14.15”.
           The exact result depends on how the TimeShort format
           for the locale is implemented in ICU.
     - \%S Seconds, as a decimal number (00-61).
     - \%t A &lt;tab&gt; character.
     - \%T 24-hour clock time, in the format HH:MM:SS.
     - \%u Weekday, as a decimal number (1(Monday)-7).
     - \%U Week number of the year (Sunday as the first day of the week) as a
       decimal number (00-53). All days in a new year preceding the first
       Sunday are considered to be in week 0.
     - \%v Same as \%V, for compatibility
     - \%V Week of the year (Monday as the first day of the week), as a decimal
       number (01-53). The method for determining the week number is as
       specified by ISO 8601.
     - \%w Weekday, as a decimal number (0(Sunday)-6).
     - \%W Week number of the year (Monday as the first day of the week), as a
       decimal number (00-53). All days in a new year preceding the first
       Monday are considered to be in week 0.
     - \%x FDCC-set’s appropriate date representation.
     - \%X FDCC-set’s appropriate time representation.
     - \%y Year within century (00-99).
     - \%Y Year with century, as a decimal number.
     - \%z The offset from UTC in the ISO 8601 format "-0430" (meaning 4 hours
       30 minutes behind UTC, west of Greenwich), or by no characters if no
       time zone is determinable.
     - \%Z Time-zone name, or no characters if no time zone is determinable.
     - \%% A &lt;percent-sign&gt; character.
    */
    QString formatDateTime(const MCalendar &mCalendar,
                           const QString &formatString) const;

    /*!
     * \brief Formats a phone number according to the given grouping
     */
    QString formatPhoneNumber( const QString& phoneNumber,
			       PhoneNumberGrouping grouping =
			       DefaultPhoneNumberGrouping ) const;

    /*!
     * \brief returns ICU date and time format string of the current locale
     * \param dateType style of date formatting
     * \param timeType style of time formatting
     * \param calendarType calendar to use for formatting
     */
    QString icuFormatString( DateType dateType = DateLong,
                              TimeType timeType = TimeLong,
                              CalendarType calendarType = DefaultCalendar) const;

    /*!
     * \brief Creates a datetime object from a string with explicit format lengths.
     * \param dateTime string to parse
     * \param dateType style of date formatting
     * \param timeType style of time formatting
     * \param calendarType calendar to use for formatting
     *
     * If dateType is MLocale::DateNone <b>and</b> timeType is MLocale::TimeNone,
     * an invalid QDateTime is returned.
     */
    QDateTime parseDateTime(const QString &dateTime, DateType dateType = DateLong,
                            TimeType timeType = TimeLong,
                            CalendarType calendarType = DefaultCalendar) const;

    /*!
     * \brief Creates a datetime object from a string with explicit calendar type.
     * \param dateTime string to parse
     * \param calendarType calendar to use
     */
    QDateTime parseDateTime(const QString &dateTime, CalendarType calendarType) const;

    /*!
     * \brief Returns the locale dependent name for a month number
     *
     * calls the 4 argument version of monthName() with
     * context = MLocale::DateSymbolStandalone and
     * symbolLength = MLocale::DateSymbolWide
     *
     * \sa QString monthName(const MCalendar &mCalendar, int monthNumber, DateSymbolContext context, DateSymbolLength symbolLength) const
     */
    QString monthName(const MCalendar &mCalendar, int monthNumber) const;

    /*!
     * \brief Returns the locale dependent name for a month choosing context and length
     *
     * \sa QString monthName(const MCalendar &mCalendar, int monthNumber) const
     */
    QString monthName(const MCalendar &mCalendar, int monthNumber,
                      DateSymbolContext context, DateSymbolLength symbolLength) const;

    /*!
     * \brief Returns locale dependent weekday name
     *
     * calls the 4 argument version of weekdayName() with
     * context = MLocale::DateSymbolStandalone and
     * symbolLength = MLocale::DateSymbolWide
     *
     * \sa weekdayName(const MCalendar &mCalendar, int weekday, DateSymbolContext context, DateSymbolLength symbolLength) const
     */
    QString weekdayName(const MCalendar &mCalendar, int weekday) const;


    /*!
     * \brief Returns locale dependent weekday name choosing context and length
     *
     * \sa weekdayName(const MCalendar &mCalendar, int weekday) const
     */
    QString weekdayName(const MCalendar &mCalendar, int weekday,
                        DateSymbolContext context, DateSymbolLength symbolLength) const;

    // TODO: add versions for QDate and QTime?

    ////////////////////////////////
    //// ID translation scheme /////

    /*!
     * \brief Copies translations from another MLocale
     * the catalogs are reloaded based on the locale settings
     */
    void copyCatalogsFrom(const MLocale &other);

    /*!
     * \brief installs a translation catalog
     * \param name of the translation catalog to install
     *
     * Adds this translation catalog to the list of translation catalogs
     * used by this MLocale.
     *
     * The list of catalogs used by the system default locale is the
     * list of catalogs which will be used when translating strings
     * with qtTrId() or tr().
     *
     * Usually the catalog name should be specified <b>without</b> the
     * “.qm” file extension and <b>without</b> the locale specific
     * part of the file name. I.e. one should usually call
     * installTrCatalog("foo") and <b>not</b>
     * installTrCatalog("foo_en_US.qm").
     *
     * If only the basename of the catalog (e.g. "foo") is specified,
     * installTrCatalog() installs both the engineering
     * English file for this catalog <b>and</b> the real translations
     * for this catalog for the locale. The engineering English
     * gets lowest priority by prepending it to the list of
     * already installed catalogs and the real translations get
     * highest priority by appending it to the list of already
     * installed catalog names.
     *
     * Example:
     *
     * Add translation catalogs “foo” and “bar” to the catalogs used
     * by the system default locale:
     *
     * \code
     * // get current system default locale
     * MLocale locale;
     * // install a translation catalog
     * // (this catalog is added to the list of catalogs already used
     * // by the system default locale):
     * locale.installTrCatalog("foo");
     * locale.installTrCatalog("bar");
     * // make the locale with the added translation catalog the new system
     * // default:
     * MLocale::setDefault(locale);
     * \endcode
     *
     * In this example, after calling locale.installTrCatalog("foo") the
     * internal list of installed catalog names of the locale looks like:
     *
     * \code
     *    "foo.qm" "bar.qm" ... previous catalog list ... "foo" "bar"
     * \endcode
     *
     * Priority in this list increases from left to right.
     *
     * Eventually, this list of catalog names is evaluated and
     * translation files are loaded from the file system.
     * The translation files are searched in the directories
     * in the translation path list, see translationPaths().
     *
     * For entries in the list of catalog names which end with “.qm”
     * the names are used “as is”, i.e. in the example above the files
     * “foo.qm” and “bar.qm” are loaded for these entries. For entries
     * in the list of catalog names which do <b>not</b> end with
     * “.qm”, a locale specific file name part and a “.qm” extension
     * is added and Qt-like fallbacks for the file name to load are
     * used.  As an example, let’s assume that the name of the locale
     * is “en_US”, then the following file names are tried to get
     * the real translations for the catalog name “foo”:
     *
     * \code
     * foo_en_US.qm
     * foo_en_US
     * foo_en.qm
     * foo_en
     * \endcode
     *
     * and the first one which exists is loaded.
     *
     * Note that the search for fallbacks for the real translation
     * stops at “foo_en”. This is slightly different from the
     * behaviour of <a
     * href="http://qt.nokia.com/doc/qtranslator.html#load">QTranslator::load()</a>
     * because proceeding to the fallback “foo.qm” would load
     * engineering English if “foo.qm” exists which is not what we
     * want when trying to load real translations because this might
     * add engineering English with the wrong priority (highest
     * priority) to the list of translation catalogs if the real
     * translation happens to be missing.
     *
     * If the settings of the locale change, the list of translation
     * catalog names is reevaluated and translations may switch to
     * a different language (see connectSettings(), disconnectSettings(),
     * settingsChanged(), localeSettingsChanged()).
     *
     * If a full file name including a “.qm” extension is specified
     * as the argument of installTrCatalog(), this catalog name is
     * always appended to the list of catalog names, i.e. used with
     * highest priority. This means that after calling
     * locale.installTrCatalog("foo_en_US.qm") the internal list
     * of installed catalog names looks like:
     *
     * \code
     *    ... previous catalog list ... "foo_en_US.qm"
     * \endcode
     *
     * This is mainly intended for testing to force loading of a fully
     * specified translation file with highest priority. Except
     * for testing this should not be used because in the above example
     * with “foo_en_US.qm”, the locale specific part does not change
     * according to the locale settings but always stays like this.
     * And loading an engineering English file by specifying
     * the full file name, i.e. installTrCatalog("foo.qm") should
     * also be used only for testing because this adds the engineering
     * English with highest priority which is usually wrong.
     *
     * After a locale has been made the system default with setDefault(),
     * the translation catalogs which have been installed into that locale
     * are available for use with qtTrId(), i.e. one can use code
     * like this to translate a string:
     *
     * \code
     * // translate a string:
     *
     * //% "Hello"
     * QString translatedString = qtTrId("hello_msg");
     * \endcode
     *
     * \sa isInstalledTrCatalog(const QString &name)
     * \sa removeTrCatalog(const QString &name)
     * \sa setDefault(const MLocale &locale)
     * \sa translationPaths()
     * \sa setTranslationPaths(const QStringList &paths)
     * \sa addTranslationPath(const QString &path)
     * \sa removeTranslationPath(const QString &path)
     */
    void installTrCatalog(const QString &name);

    /*!
     * \brief removes a translation catalog
     * \param name of the translation catalog to remove
     *
     * Removes the catalog from the list of translation catalogs used by this
     * MLocale.
     *
     * \sa isInstalledTrCatalog(const QString &name)
     * \sa installTrCatalog(const QString &name)
     */
    void removeTrCatalog(const QString &name);

    /*!
     * \brief checks whether a translation catalog is installed nor not
     * \param name of the translation catalog to check
     *
     * returns true if such a translation catalog has been installed
     * already, false if not.
     *
     * \sa installTrCatalog(const QString &name)
     * \sa removeTrCatalog(const QString &name)
     */
    bool isInstalledTrCatalog(const QString &name) const;

    /*!
     * \brief tr() compatibility translation method.
     * \param context context of the translation
     * \param sourceText text to translate
     * \param comment about the translation. may be helpful when creating translation files
     * \param n plurality
     */
    QString translate(const char *context, const char *sourceText,
                      const char *comment = 0, int n = -1);

    /*!
     * \brief converts all digits in the input to localized digits
     * \param text a string which may contain various localized digits
     *
     * This converts all digits in the input, whether they are already
     * localized or not, into digits localized for the current locale.
     *
     * For example, if the input contains Devanagari digits and
     * Latin digits, and if the current locale uses Eastern Arabic
     * digits, both the Devanagari digits and the Latin digits
     * are converted to Eastern Arabic digits.
     *
     * Only digits are changed, nothing else, except if the target
     * digits are Latin digits, then it behaves like
     * toLatinNumbers(const QString &text) which removes directional
     * formatting codes as well.
     *
     * \sa toLocalizedNumbers(const QString &text, const QString &targetDigits)
     * \sa toLatinNumbers(const QString &text)
     */
    QString toLocalizedNumbers(const QString &text) const;

    /*!
     * \brief converts all localized digits in the input to the given localized digits
     * \param text a string which may contain various localized digits
     * \param targetDigits a string of length 10 containing the target digits
     *
     * This is static, i.e. it does <b>not</b> depend on a specific
     * locale.
     *
     * It converts all sorts of localized digits, for example
     * Eastern Arabic digits, Devanagari digits, CJK full-width digits
     * ... to the digits in the string given as the second parameter.
     * The string given as the second parameter <b>must</b> have
     * <b>exactly</b> a length of 10 specifying the digits of the
     * desired target numbering system.
     *
     * Only digits are changed, nothing else, except if the target
     * digits are "0123456789", i.e. Latin digits, then it removes
     * directional formatting codes as well, i.e. it behaves like
     * like toLatinNumbers(const QString &text).
     *
     * \sa toLocalizedNumbers(const QString &text)
     * \sa toLatinNumbers(const QString &text)
     */
    static QString toLocalizedNumbers(const QString &text, const QString &targetDigits);

    /*!
     * \brief converts all localized digits in the input to Latin digits
     * \param text a string which may contain various localized digits
     *
     * This is static, i.e. it does <b>not</b> depend on a specific
     * locale.
     *
     * It converts all sorts of localized digits, for example
     * Eastern Arabic digits, Devanagari digits, CJK full-width digits
     * ... to the usual Latin digits. 
     *
     * On top of that, it removes directional formatting codes like
     * RLM markers, strings containing numbers in Arabic may
     * contain such markers, they should be removed when converting
     * to Latin numbers.
     *
     * Other characters in the input apart from digits and directional
     * formatting codes are returned unchanged.
     *
     * \sa toLocalizedNumbers(const QString &text)
     * \sa toLocalizedNumbers(const QString &text, const QString &targetDigits)
     */
    static QString toLatinNumbers(const QString &text);

    /*!
     * \brief Sets the DataPaths for the (ICU) locale system to the given paths.
     *
     * \param dataPaths a list of paths
     *
     * This should be called at most once in a process before creating
     * any MLocale instances. This function is <b>not</b> thread-safe.
     * Use it before doing anything with MLocale instances from multiple
     * threads.
     *
     * This function calls u_setDataDirectory() in libicu, see also
     * <a href="http://icu-project.org/apiref/icu4c/putil_8h.html">
     * http://icu-project.org/apiref/icu4c/putil_8h.html</a>.
     *
     * libmeegotouch initialises this data path to the value of the macro
     *
     * \code
     *     M_ICUEXTRADATA_DIR
     * \endcode
     *
     * which is normally set to
     *
     * \code
     *     /usr/share/mlocale/icu/
     * \endcode
     *
     * usually one should not change this.
     *
     * The user data itself should be in the ICU specific
     * subdirectories at the given paths, e.g. a user override file
     * for some of the basic data of the Finnish locale should be
     * in
     *
     * \code
     *     /usr/share/mlocale/icu/usrdt42l/fi.res
     * \endcode
     *
     * and a user override file for the lang data of the Finnish
     * locale should be in
     *
     * \code
     *     /usr/share/mlocale/icu/usrdt42l/lang/fi.res
     * \endcode
     *
     * etc.
     *
     * \sa void setDataPath(const QString &dataPath)
     * \sa dataPaths()
     */
    static void setDataPaths(const QStringList &dataPaths);

    /*!
     * \brief Sets the data paths used by ICU to the given path
     *
     * \param dataPath the data path
     *
     * convenience function to set the data path used by ICU
     * to a single directory
     *
     * \sa setDataPaths(const QStringList &dataPaths)
     * \sa dataPaths()
     */
    static void setDataPath(const QString &dataPath);

    /*!
     * \brief Returns the list of data paths used by ICU
     *
     * \sa setDataPaths(const QStringList &dataPaths)
     * \sa setDataPath(const QString &dataPath)
     */
    static QStringList dataPaths();

    /*!
     * \brief Sets the paths that are used as base directories for using translations
     * The translation path modification methods are not thread-safe.
     *
     * The default translation path is
     *
     * \verbatim
     *    /usr/share/l10n/meegotouch
     * \endverbatim
     *
     * i.e. if none of the translation path modification methods is
     * used, the list of translation paths contains only this entry.
     *
     * \sa  translationPaths()
     * \sa addTranslationPath(const QString &path)
     * \sa removeTranslationPath(const QString &path)
     */
    static void setTranslationPaths(const QStringList &paths);

    /*!
     * \brief Append a path to the translation file lookup directories.
     *
     * If the path to be added is already in the list of translation
     * paths, nothing happens, i.e. the path is not appended again to
     * the end of the path list.
     *
     * \sa translationPaths()
     * \sa setTranslationPaths(const QStringList &paths)
     * \sa removeTranslationPath(const QString &path)
     */
    static void addTranslationPath(const QString &path);

    /*!
     * \brief Removes a path
     *
     * \sa translationPaths()
     * \sa setTranslationPaths(const QStringList &paths)
     * \sa addTranslationPath(const QString &path)
     */
    static void removeTranslationPath(const QString &path);

    /*!
     * \brief Returns the list of current translation file base paths
     *
     * \sa setTranslationPaths(const QStringList &paths)
     * \sa addTranslationPath(const QString &path)
     * \sa removeTranslationPath(const QString &path)
     */
    static QStringList translationPaths();

    /*!
     * \brief Monitors all changes in the locale related gconf keys
     *
     * After calling this method, all changes in the locale related
     * gconf keys will change this locale according to the changes in the
     * gconf keys, and emit the settingsChanged() signal.
     */
    void connectSettings();

    /*!
     * \brief Disconnects from change monitoring in settings
     * After calling this method, all changes in the settings
     * will no longer emit settingsChanged() signal
     */
    void disconnectSettings();

    /*!
     * \brief Static method to obtain primary script of locale.
     * Can be used to obtain primary script without instantiating MLocale,
     * useful when obtaining a list of scripts for a lot of languages. Primary
     * script means a script returned by script() or first item in
     * languageScripts().
     */
    static QString localeScript(const QString &locale);

    /*!
     * \brief Static method to obtain endonym for locale.
     * Can be used to obtain endonym without instantiating MLocale, useful
     * when obtaining a list of endonyms for a lot of languages.
     */
    static QString languageEndonym(const QString &locale);

    /*!
     * \brief Static method to obtain the text direction for a given text.
     *
     * This returns the text direction for a (paragraph) of text
     * according to the rules to determine the <a
     * href="http://unicode.org/reports/tr9/#The_Paragraph_Level">
     * Paragraph Level in the Unicode Bidirectional Algorithm</a>.
     * I.e. it looks for the first character of L, AL, or R in the
     * paragraph, if such a character is found and it is of type AL or
     * R, the text direction is Qt::RightToLeft else Qt::LeftToRight.
     *
     * If the text is empty or if it only contains digits, whitespace,
     * punctuation characters or other characters with no strong text
     * direction, this function returns Qt::LayoutDirectionAuto.
     *
     * Notice that this will only work well for plain text; rich text
     * might contain markup tags (e.g., \<b\>) that might also be
     * detected as having a meaningful text direction.
     *
     * \sa textDirection() const
     * \sa defaultLayoutDirection()
     */
    static Qt::LayoutDirection directionForText(const QString & text);

    /*!
     * \brief Static method to obtain the layout direction of the default locale
     *
     * This returns the layout direction of the system default locale,
     * i.e. of the locale which has been set with setDefault().
     *
     * See the longer explanation at textDirection() for what layout
     * direction is returned depending on the locale id.
     *
     * \sa textDirection() const
     * \sa directionForText(const QString & text)
     * \sa setDefault(const MLocale &locale)
     */
    static Qt::LayoutDirection defaultLayoutDirection();

Q_SIGNALS:
    void settingsChanged();
    /*!
     * \brief Signal emitted when the default system locale changes.
     */
    void localeSettingsChanged();

protected:

    /*!
     * \brief Returns the default locale object.
     */
    static MLocale &getDefault();

private:
    // not implemented now
    bool operator==(const MLocale &other) const;
    bool operator!=(const MLocale &other) const;

    // global default locale
    static MLocale *s_systemDefault;
    // private info is kept away from the public header
    MLocalePrivate *const d_ptr;
    Q_DECLARE_PRIVATE(MLocale)

    friend class MCalendar;
    friend class MCollator;
    friend struct MStaticLocaleDestroyer;
    friend class MIcuBreakIteratorPrivate;

private Q_SLOTS:
    void refreshSettings();
};

}

#endif
